home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-19 / intrlib1.zip / SAVEIMAG.C < prev    next >
C/C++ Source or Header  |  1992-02-20  |  13KB  |  367 lines

  1. /******************************************************************************
  2. * Iteraction library - save/restore bitmaps.                      *
  3. *                                          *
  4. *                    Written by Gershon Elber,  Oct. 1990  *
  5. *******************************************************************************
  6. * History:                                      *
  7. *  3 Oct 90 - Version 1.0 by Gershon Elber.                      *
  8. ******************************************************************************/
  9.  
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <io.h>
  13. #include <fcntl.h>
  14. #ifdef __MSDOS__
  15. #include <sys\stat.h>
  16. #endif /* __MSDOS__ */
  17. #include "intr_loc.h"
  18. #include "intr_gr.h"
  19. #ifdef __MSDOS__
  20. #include "intr_ems.h"
  21. #endif /* __MSDOS__ */
  22.  
  23. #define MAX_NUM_SAVE_IMAGE    20
  24. #define MAX_ASYNC_EVENTS    (MAX_NUM_SAVE_IMAGE - 5)
  25.  
  26. typedef struct IntrSaveMemStruct {
  27.     struct IntrSaveMemStruct *Pnext;       /* If has more save mem. structs. */
  28.     int Xmin, Ymin, Xmax, Ymax;
  29.     int Handle, LineSize, NumOfLines, LinesPerPage;
  30.     union {
  31.         void *Buffer;     /* Pointer to real memory buffer if in real memory. */
  32.         char *FileName;   /* Pointer to full path file name if save on disk. */
  33. #ifdef DJGCC
  34.     void *Region;/* struct GrRegion actually, but hidden by intr_djg.cc. */
  35. #endif /* DJGCC */
  36.     } U;
  37. } IntrSaveMemStruct;
  38.  
  39. /* If _IntrSaveBelow is TRUE, the image below the pop up window is saved and */
  40. /* restored once done. This requires the usage of temporary memory.         */
  41. /* If _IntrSaveBelow is FALSE, the windows below should be refreshed. This   */
  42. /* is usually slower but no image saving is required.                 */
  43. IntrBType _IntrSaveBelow = TRUE;
  44.  
  45. static IntrSaveMemType
  46.     SaveMemMethod = INTR_SAVE_CONV,
  47.     AllowAsyncEvents = FALSE;
  48.  
  49. static char
  50.     *TempFileName = "Intr$Tmp.SM1",
  51.     *TempFilePath = NULL;
  52.  
  53. static int
  54.     NumOfSavedImages = 0;
  55. static IntrSaveMemStruct
  56.     *SaveMemAllRoots[MAX_NUM_SAVE_IMAGE];
  57.  
  58. /****************************************************************************
  59. * Function to control if internal events are to be handled.            *
  60. ****************************************************************************/
  61. IntrBType _IntrAllowInternalEvent(void)
  62. {
  63.     if (NumOfSavedImages == 0) return TRUE;
  64.  
  65.     return AllowAsyncEvents && NumOfSavedImages < MAX_ASYNC_EVENTS;
  66. }
  67.  
  68. /****************************************************************************
  69. * Function to control if internal events are to be handled.            *
  70. ****************************************************************************/
  71. void IntrSetAsyncEventMode(IntrBType AsyncMode)
  72. {
  73.     AllowAsyncEvents = AsyncMode;
  74. }
  75.  
  76. /****************************************************************************
  77. * Function returns number of pop up items.                    *
  78. ****************************************************************************/
  79. int IntrPopUpActive(void)
  80. {
  81.     return NumOfSavedImages;
  82. }
  83.  
  84. /****************************************************************************
  85. * Set back saving flag.                                *
  86. ****************************************************************************/
  87. void IntrSetSaveBackGround(IntrBType SaveBackGround)
  88. {
  89.     if (NumOfSavedImages > 0)
  90.     IntrFatalError("Can not change image save method while image saved.");
  91.  
  92.     _IntrSaveBelow = SaveBackGround;
  93. }
  94.  
  95. /****************************************************************************
  96. * Set back saving method. See IntrSameMemType for methods.            *
  97. ****************************************************************************/
  98. void IntrSetSaveBackMethod(IntrSaveMemType SaveBackMethod)
  99. {
  100.     if (NumOfSavedImages > 0)
  101.     IntrFatalError("Can not change image save method while image saved.");
  102.  
  103.     SaveMemMethod = SaveBackMethod;
  104.  
  105.     switch(SaveMemMethod) {
  106.     case INTR_SAVE_CONV:
  107.         break;
  108. #ifdef __MSDOS__
  109.     case INTR_SAVE_EMS:
  110.         if (!EMSDetected())
  111.                 IntrFatalError("EMS driver not detected.");
  112.             break;
  113.     case INTR_SAVE_XMS:
  114.         IntrFatalError("XMS not implemented.");
  115.             break;
  116.     case INTR_SAVE_DISK:
  117.         break;
  118. #endif /* __MSDOS__ */
  119.     }
  120. }
  121.  
  122. /****************************************************************************
  123. * Set path to save images on disk. Default is current directory.        *
  124. * This path is used to save images if method is INTR_SAVE_DISK.            *
  125. ****************************************************************************/
  126. void IntrSetSaveBackPath(char *Path)
  127. {
  128.     if (NumOfSavedImages > 0)
  129.     IntrFatalError("Can not change image save method while image saved.");
  130.  
  131.     if (TempFilePath != NULL) _IntrFree(TempFilePath);
  132.  
  133.     if (Path != NULL)
  134.         TempFilePath = strdup(Path);
  135.     else
  136.         TempFilePath = NULL;
  137. }
  138.  
  139.  
  140. /****************************************************************************
  141. * Saves the content of the image buffer specified by the BBox below.        *
  142. ****************************************************************************/
  143. void _IntrSaveWindow(int Xmin, int Ymin, int Xmax, int Ymax)
  144. {
  145.     void *Buffer;
  146.     char Name[80];
  147.     int Handle, y, Page;
  148.     unsigned long Size;
  149.     unsigned int NumOfPages, LinesInOne, YmaxTmp, LineSize;
  150.     IntrSaveMemStruct *SaveMem,
  151.     *SaveMemRoot = NULL,
  152.     *SaveMemTail = NULL;
  153.  
  154.     if (Xmin < 0) Xmin = 0;
  155.     if (Ymin < 0) Ymin = 0;
  156.     if (Xmax > GRScreenMaxX) Xmax = GRScreenMaxX;
  157.     if (Ymax > GRScreenMaxY) Ymax = GRScreenMaxY;
  158.  
  159.     if (NumOfSavedImages >= MAX_NUM_SAVE_IMAGE)
  160.     IntrFatalError("Save image stack overflow.");
  161.  
  162. #ifdef __MSDOS__
  163.     Size = (unsigned long) GRGetImageBufferSize(Xmin, Ymin, Xmax, Ymax);
  164.     LineSize = GRGetImageBufferSize(Xmin, 0, Xmax, 0);
  165.  
  166.     /* Size is bigger than 64k - find real size. */
  167.     if (Size == 0xffffL)
  168.         Size = (Ymax - Ymin) * ((unsigned long) LineSize);
  169. #endif /* __MSDOS__ */
  170.  
  171.     switch (SaveMemMethod) {
  172.         default:
  173.     case INTR_SAVE_CONV:
  174. #ifdef __MSDOS__
  175.         if (Size > 0xffffL) {               /* Need to save in parts. */
  176.         LinesInOne = 32767 / LineSize;     /* Approx. 32k each time. */
  177.                 while (Ymin < Ymax) {
  178.             SaveMem = (IntrSaveMemStruct *)
  179.                               _IntrMalloc(sizeof(IntrSaveMemStruct));
  180.                     SaveMem -> Pnext = NULL;
  181.                     SaveMem -> Xmin = Xmin;
  182.                     SaveMem -> Ymin = Ymin;
  183.                     SaveMem -> Xmax = Xmax;
  184.                     SaveMem -> Ymax = Ymax;
  185.                     YmaxTmp = MIN(Ymin + LinesInOne, Ymax);
  186.                     SaveMem -> U.Buffer =
  187.                         _IntrMalloc(GRGetImageBufferSize(Xmin, Ymin,
  188.                                         Xmax, YmaxTmp));
  189.                     GRGetImageBuffer(Xmin, Ymin, Xmax, YmaxTmp,
  190.                                  SaveMem -> U.Buffer);
  191.                     Ymin = YmaxTmp;
  192.  
  193.                     if (SaveMemRoot != NULL) {
  194.                         SaveMemTail -> Pnext = SaveMem;
  195.             SaveMemTail = SaveMem;
  196.                     }
  197.                     else {
  198.                         SaveMemRoot = SaveMemTail = SaveMem;
  199.                     }
  200.                 }
  201.             }
  202.             else
  203. #endif /* __MSDOS__ */
  204.         {
  205.         SaveMemRoot = (IntrSaveMemStruct *)
  206.                               _IntrMalloc(sizeof(IntrSaveMemStruct));
  207.                 SaveMemRoot -> Pnext = NULL;
  208.                 SaveMemRoot -> Xmin = Xmin;
  209.                 SaveMemRoot -> Ymin = Ymin;
  210.                 SaveMemRoot -> Xmax = Xmax;
  211.                 SaveMemRoot -> Ymax = Ymax;
  212. #ifdef __MSDOS__
  213.                 SaveMemRoot -> U.Buffer = _IntrMalloc((unsigned int) Size);
  214.                 GRGetImageBuffer(Xmin, Ymin, Xmax, Ymax,
  215.                          SaveMemRoot -> U.Buffer);
  216. #endif /* __MSDOS__ */
  217. #ifdef DJGCC
  218.         SaveMemRoot -> U.Region = GRGetImageBuffer(Xmin, Ymin,
  219.                                Xmax, Ymax);
  220. #endif /* DJGCC */
  221.             }
  222.             break;
  223. #ifdef __MSDOS__
  224.     case INTR_SAVE_EMS:
  225.         LinesInOne = 15000 / LineSize;           /* Approx. 15k in page. */
  226.             NumOfPages = (Ymax - Ymin + 1) / LinesInOne + 1;
  227.             if (NumOfPages > 1)
  228.         printf("");
  229.         SaveMemRoot = (IntrSaveMemStruct *)
  230.                               _IntrMalloc(sizeof(IntrSaveMemStruct));
  231.             if ((SaveMemRoot -> Handle = EMSAlloc(NumOfPages)) == 0)
  232.                 IntrFatalError("Fail to EMS allocate.");
  233.             SaveMemRoot -> Pnext = NULL;
  234.             SaveMemRoot -> Xmin = Xmin;
  235.             SaveMemRoot -> Ymin = Ymin;
  236.             SaveMemRoot -> Xmax = Xmax;
  237.             SaveMemRoot -> Ymax = Ymax;
  238.             SaveMemRoot -> LineSize = LineSize;
  239.             SaveMemRoot -> NumOfLines = Ymax - Ymin + 1;
  240.             SaveMemRoot -> LinesPerPage = LinesInOne;
  241.  
  242.             Page = 0;
  243.             while (Ymin < Ymax) {
  244.             if ((Buffer = EMSMap(SaveMemRoot -> Handle, Page++, 0)) == NULL)
  245.                 IntrFatalError("Fail to EMS Map.");
  246.                 YmaxTmp = MIN(Ymin + LinesInOne - 1, Ymax);
  247.                 GRGetImageBuffer(Xmin, Ymin, Xmax, YmaxTmp, Buffer);
  248.                 Ymin += LinesInOne;
  249.             }
  250.             break;
  251.     case INTR_SAVE_XMS:
  252.             break;
  253.     case INTR_SAVE_DISK:
  254.         /* Save into disk one line at a time. */
  255.             if (TempFilePath != NULL)
  256.                 strcpy(Name, TempFilePath);
  257.             else
  258.                 Name[0] = 0;
  259.             strcat(Name, TempFileName);
  260.             Name[strlen(Name) - 1] = 'A' + NumOfSavedImages;
  261.             if ((Handle = open(Name,
  262.                                O_RDWR | O_CREAT | O_BINARY,
  263.                                S_IREAD | S_IWRITE)) < 0)
  264.                 IntrFatalError("Fail to open image disk file.");
  265.  
  266.             Buffer = _IntrMalloc(LineSize);
  267.         SaveMemRoot = (IntrSaveMemStruct *)
  268.                               _IntrMalloc(sizeof(IntrSaveMemStruct));
  269.             SaveMemRoot -> Pnext = NULL;
  270.             SaveMemRoot -> Xmin = Xmin;
  271.             SaveMemRoot -> Ymin = Ymin;
  272.             SaveMemRoot -> Xmax = Xmax;
  273.             SaveMemRoot -> Ymax = Ymax;
  274.             SaveMemRoot -> LineSize = LineSize;
  275.             SaveMemRoot -> NumOfLines = Ymax - Ymin + 1;
  276.             SaveMemRoot -> U.FileName = strdup(Name);
  277.             for (y = Ymin; y <= Ymax; y++) {
  278.                 GRGetImageBuffer(Xmin, y, Xmax, y, Buffer);
  279.         write(Handle, Buffer, LineSize);
  280.             }
  281.             _IntrFree(Buffer);
  282.             close(Handle);
  283.         break;
  284. #endif /* __MSDOS__ */
  285.     }
  286.  
  287.     SaveMemAllRoots[NumOfSavedImages++] = SaveMemRoot;
  288. }
  289.  
  290. /****************************************************************************
  291. * Free all saved images in case of async. exit.                    *
  292. ****************************************************************************/
  293. void _IntrRestoreAll(void)
  294. {
  295.     while (NumOfSavedImages > 0) _IntrRestoreWindow();
  296. }
  297.  
  298. /****************************************************************************
  299. * Restores the content of the image buffer specified by SaveMemRoot.        *
  300. ****************************************************************************/
  301. void _IntrRestoreWindow(void)
  302. {
  303.     int Handle, y, LinesPerPage, Page;
  304.     void *Buffer;
  305.     IntrSaveMemStruct *SaveMem, *SaveMemRoot;
  306.  
  307.     if (NumOfSavedImages <= 0)
  308.     IntrFatalError("Save image stack underflow.");
  309.     SaveMemRoot = SaveMemAllRoots[--NumOfSavedImages];
  310.  
  311.     switch (SaveMemMethod) {
  312.     default:
  313.     case INTR_SAVE_CONV:
  314.             while (SaveMemRoot != NULL) {
  315.                 SaveMem = SaveMemRoot;
  316.                 SaveMemRoot = SaveMemRoot -> Pnext;
  317. #ifdef __MSDOS__
  318.                 GRPutImageBuffer(SaveMem -> Xmin, SaveMem -> Ymin,
  319.                          SaveMem -> U.Buffer);
  320.                 _IntrFree(SaveMem -> U.Buffer);
  321. #endif /* __MSDOS__ */
  322. #ifdef DJGCC
  323.                 GRPutImageBuffer(SaveMem -> Xmin, SaveMem -> Ymin,
  324.                          SaveMem -> U.Region);
  325. #endif /* DJGCC */
  326.                 _IntrFree(SaveMem);
  327.             }
  328.             break;
  329. #ifdef __MSDOS__
  330.     case INTR_SAVE_EMS:
  331.             y = SaveMemRoot -> Ymin;
  332.             LinesPerPage = SaveMemRoot -> LinesPerPage;
  333.  
  334.             Page = 0;
  335.             while (y < SaveMemRoot -> Ymax) {
  336.             if ((Buffer = EMSMap(SaveMemRoot -> Handle, Page++, 0)) == NULL)
  337.                 IntrFatalError("Fail to EMS Map.");
  338.                 GRPutImageBuffer(SaveMemRoot -> Xmin, y, Buffer);
  339.                 y += LinesPerPage;
  340.             }
  341.             EMSFree(SaveMemRoot -> Handle);
  342.             _IntrFree(SaveMemRoot);
  343.             break;
  344.     case INTR_SAVE_XMS:
  345.             break;
  346.     case INTR_SAVE_DISK:
  347.         /* Read from disk one line at a time. */
  348.             Buffer = _IntrMalloc(SaveMemRoot -> LineSize);
  349.             if ((Handle = open(SaveMemRoot -> U.FileName,
  350.                                O_RDONLY | O_BINARY,
  351.                                S_IREAD)) < 0)
  352.                 IntrFatalError("Fail to open image disk file.");
  353.  
  354.             for (y = SaveMemRoot -> Ymin; y <= SaveMemRoot -> Ymax; y++) {
  355.         read(Handle, Buffer, SaveMemRoot -> LineSize);
  356.                 GRPutImageBuffer(SaveMemRoot -> Xmin, y, Buffer);
  357.             }
  358.             _IntrFree(Buffer);
  359.             close(Handle);
  360.             unlink(SaveMemRoot -> U.FileName);         /* Delete the file. */
  361.             _IntrFree(SaveMemRoot -> U.FileName);
  362.             _IntrFree(SaveMemRoot);
  363.         break;
  364. #endif /* __MSDOS__ */
  365.     }
  366. }
  367.